/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       heightfield.h
 * Author:     karooolek
 * Created on: 2009-09-30
 *
 **********************************************************************************************************************/

#ifndef HEIGHTFIELD_H_
#define HEIGHTFIELD_H_

#include "vector3.h"
#include "shape.h"
#include <cstring>

namespace mGameEngine
{

/**
 * Heightfield shape.
 */
class Heightfield : public Shape
{
private:
    /**
     * Size.
     */
    Vector3 _size;

    /**
     * Position.
     */
    Vector3 _position;

    /**
     * Columns count.
     */
    uint _columns;

    /**
     * Rows count.
     */
    uint _rows;

    /**
     * Heights data.
     */
    float *_heights;

public:
    /**
     * Create heightfield shape.
     */
    Heightfield();

    /**
     * Create heightfield shape with specified size, position and heights data.
     * @param size size.
     * @param position position.
     * @param columns columns count.
     * @param rows rows count.
     * @param heights heights data.
     */
    Heightfield(const Vector3 &size,
        const Vector3 &position,
        uint columns, uint rows, float *heights);

    /**
     * Destroy heightfield.
     */
    ~Heightfield();

    /**
     * Get heightfield shape size.
     * @return heightfield shape size.
     */
    const Vector3 &getSize() const
    {
        return _size;
    }

    /**
     * Set heightfield shape size.
     * @param heightfield shape size.
     */
    void setSize(const Vector3 &size)
    {
        _size = size;
    }

    /**
     * Get heightfield shape position.
     * @return heightfield shape position.
     */
    const Vector3 &getPosition() const
    {
        return _position;
    }

    /**
     * Set heightfield shape position.
     * @param heightfield shape position.
     */
    void setPosition(const Vector3 &position)
    {
        _position = position;
    }

    /**
     * Get heightfield shape columns count.
     * @return heightfield shape columns count.
     */
    uint getColumns() const
    {
        return _columns;
    }
    
    /**
     * Get heightfield shape rows count.
     * @return heightfield shape rows count.
     */
    uint getRows() const
    {
        return _rows;
    }

    /**
     * Get heightfield shape heights data.
     * @return heightfield shape heights data.
     */
    const float *getHeights() const
    {
        return _heights;
    }

    /**
     * Set heightfield shape heights data.
     * @param columns columns count.
     * @param rows rows count.
     * @param heights heights data.
     */
    virtual void setHeights(uint columns, uint rows, float *heights);

    /**
     * Get heightfield shape height at specified position.
     * @param position position.
     * @return heightfield shape height at position or 0 outside heightfield shape.
     */
    virtual float getHeightAt(const Vector2 &position) const;

    /**
     * Get heightfield shape normal at specified position.
     * @param position position.
     * @return heightfield shape normal at position or up vector outside heightfield shape.
     */
    virtual Vector3 getNormalAt(const Vector2 &position) const;

    /**
     * Get heightfield shape slope at specified position.
     * @param position position.
     * @return heightfield shape slope in radians at position or zero outside heightfield shape.
     */
    virtual float getSlopeAt(const Vector2 &position) const;
};

}

#endif // HEIGHTFIELD_H_
